package org.zcode.generator.core.generator.method;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.zcode.generator.core.config.BeanTypeConfig;
import org.zcode.generator.core.config.XmlConfig;
import org.zcode.generator.core.generator.MethodCreator;
import org.zcode.generator.core.util.GeneratorUtil;

import java.util.List;

/**
 * @Description:
 * @author zhoulk
 * @date: 2019/10/31
 */
public class DAOTestMethodCreator implements MethodCreator {
    private FullyQualifiedJavaType interfaceType;
    private IntrospectedTable introspectedTable;
    private BeanTypeConfig beanConfig;

    public DAOTestMethodCreator(XmlConfig xmlConfig,
                                BeanTypeConfig beanConfig,
                                IntrospectedTable introspectedTable) {
        this.interfaceType = beanConfig.daoType;
        this.introspectedTable = introspectedTable;
        this.beanConfig = beanConfig;
    }

    @Override
    public Method qryByIdMethod(String tableName, int flag) {
        if (introspectedTable.getPrimaryKeyColumns() == null || introspectedTable.getPrimaryKeyColumns().size() == 0) {
            return null;
        }
        Method method = new Method();
        method.setName("testQry" + tableName);
        method.addAnnotation("@Test");
        method.setVisibility(JavaVisibility.PUBLIC);

        StringBuilder sb = new StringBuilder();
//        sb.append(beanConfig.pojoType.getShortName());
//        sb.append(" ").append("result").append(" = ");
        String primaryKey = "Id";
        if (introspectedTable.getPrimaryKeyColumns() != null) {
            primaryKey = introspectedTable.getPrimaryKeyColumns().get(0).getJavaProperty();
            primaryKey = primaryKey.substring(0, 1).toUpperCase() + primaryKey.substring(1);
        }
        sb.append(GeneratorUtil.toLowerCase(interfaceType.getShortName())).append(".select").append(tableName).append("By").append(primaryKey);
        sb.append("(");
        sb.append(GeneratorUtil.randomInt());
        if (introspectedTable.getPrimaryKeyColumns() != null) {
            String type = introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType().getShortName();
            sb.append(type.equals("Long") ? "L" : "");
        }
        sb.append(");");
        method.addBodyLine(sb.toString());
//        method.addBodyLine("LOGGER.info(result.toString());");
        return method;
    }

    /**
     * 添加数量统计方法
     */
    @Override
    public Method countMethod(String tableName, int flag) {
        Method method = new Method();
        method.setName("testCount" + tableName);
        method.addAnnotation("@Test");
        method.setVisibility(JavaVisibility.PUBLIC);

        StringBuilder sb = new StringBuilder();
        String conditonType = beanConfig.pojoConditionType.getShortName();
        String condition = GeneratorUtil.toLowerCase(conditonType);
        sb.append(conditonType).append(" ").append(condition).append(" = new ").append(conditonType).append("();");
        method.addBodyLine(sb.toString());
        sb.setLength(0);
        List<IntrospectedColumn> baseColumns = introspectedTable.getBaseColumns();
        for (int i = 0; i < baseColumns.size() / 2; i++) {
            IntrospectedColumn column = baseColumns.get(i);
            sb.setLength(0);
            String columnName = column.getJavaProperty();
            columnName = columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
            sb.append(condition).append(".set").append(columnName);
            if (column.getFullyQualifiedJavaType().getShortName().equals("String")) {
                sb.append("(").append("\"cs_").append(GeneratorUtil.randomInt()).append("\");");
                method.addBodyLine(sb.toString());
            }
            if (column.getFullyQualifiedJavaType().getShortName().equals("Integer")) {
                sb.append("(").append(GeneratorUtil.randomInt()).append(");");
                method.addBodyLine(sb.toString());
            }
            if (column.getFullyQualifiedJavaType().getShortName().equals("Long")) {
                sb.append("(").append(GeneratorUtil.randomInt()).append("L);");
                method.addBodyLine(sb.toString());
            }
        }
        sb.setLength(0);
//        sb.append("Integer result = ");
        sb.append(GeneratorUtil.toLowerCase(interfaceType.getShortName())).append(".count").append(tableName).append("ByCondition");
        sb.append("(");
        sb.append(condition);
        sb.append(");");
        method.addBodyLine(sb.toString());
//        method.addBodyLine("LOGGER.info(result.toString());");
        return method;
    }

    /**
     * 列表查询接口
     */
    @Override
    public Method qrysMethod(String tableName, int flag) {
        Method method = new Method();
        method.setName("testQry" + tableName + "s");
        method.addAnnotation("@Test");
        method.setVisibility(JavaVisibility.PUBLIC);
        StringBuilder sb = new StringBuilder();
        String conditonType = beanConfig.pojoConditionType.getShortName();
        String condition = GeneratorUtil.toLowerCase(conditonType);
        sb.append(conditonType).append(" ").append(condition).append(" = new ").append(conditonType).append("();");
        method.addBodyLine(sb.toString());
        sb.setLength(0);
        List<IntrospectedColumn> baseColumns = introspectedTable.getBaseColumns();
        for (int i = 0; i < baseColumns.size() / 2; i++) {
            IntrospectedColumn column = baseColumns.get(i);
            sb.setLength(0);
            String columnName = column.getJavaProperty();
            columnName = columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
            sb.append(condition).append(".set").append(columnName);
            if (column.getFullyQualifiedJavaType().getShortName().equals("String")) {
                sb.append("(").append("\"cs_").append(GeneratorUtil.randomInt()).append("\");");
                method.addBodyLine(sb.toString());
            }
            if (column.getFullyQualifiedJavaType().getShortName().equals("Integer")) {
                sb.append("(").append(GeneratorUtil.randomInt()).append(");");
                method.addBodyLine(sb.toString());
            }
            if (column.getFullyQualifiedJavaType().getShortName().equals("Long")) {
                sb.append("(").append(GeneratorUtil.randomInt()).append("L);");
                method.addBodyLine(sb.toString());
            }
        }
        sb.setLength(0);
//        sb.append("List<").append(beanConfig.pojoType.getShortName()).append("> result = ");
        sb.append(GeneratorUtil.toLowerCase(interfaceType.getShortName())).append(".select").append(tableName).append("ByCondition");
        sb.append("(");
        sb.append(condition);
        sb.append(");");
        method.addBodyLine(sb.toString());
//        method.addBodyLine("LOGGER.info(result.toString());");


        return method;
    }

    /**
     * 更新接口
     * @param tableName
     * @param flag
     * @return
     */
    @Override
    public Method updMethod(String tableName, int flag) {
        Method method = new Method();
        method.setName("testUpd" + tableName);
        method.addAnnotation("@Test");
        method.setVisibility(JavaVisibility.PUBLIC);


        StringBuilder sb = new StringBuilder();
        String beanType = beanConfig.pojoType.getShortName();
        String bean = GeneratorUtil.toLowerCase(beanType);
        sb.append(beanType).append(" ").append(bean).append(" = new ").append(beanType).append("();");
        method.addBodyLine(sb.toString());
        sb.setLength(0);
        List<IntrospectedColumn> baseColumns = introspectedTable.getBaseColumns();
        for (int i = 0; i < baseColumns.size() / 2; i++) {
            IntrospectedColumn column = baseColumns.get(i);
            sb.setLength(0);
            String columnName = column.getJavaProperty();
            columnName = columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
            sb.append(bean).append(".set").append(columnName);
            if (column.getFullyQualifiedJavaType().getShortName().equals("String")) {
                sb.append("(").append("\"cs_").append(GeneratorUtil.randomInt()).append("\");");
                method.addBodyLine(sb.toString());
            }
            if (column.getFullyQualifiedJavaType().getShortName().equals("Integer")) {
                sb.append("(").append(GeneratorUtil.randomInt()).append(");");
                method.addBodyLine(sb.toString());
            }
            if (column.getFullyQualifiedJavaType().getShortName().equals("Long")) {
                sb.append("(").append(GeneratorUtil.randomInt()).append("L);");
                method.addBodyLine(sb.toString());
            }
        }
        sb.setLength(0);
//        sb.append("Integer result = ");
        String primaryKey = "Id";
        if (introspectedTable.getPrimaryKeyColumns() != null && introspectedTable.getPrimaryKeyColumns().size() > 0) {
            primaryKey = introspectedTable.getPrimaryKeyColumns().get(0).getJavaProperty();
            primaryKey = primaryKey.substring(0, 1).toUpperCase() + primaryKey.substring(1);
        }
        sb.append(GeneratorUtil.toLowerCase(interfaceType.getShortName())).append(".update").append(tableName).append("By").append(primaryKey);
        sb.append("(");
        sb.append(bean);
        sb.append(");");
        method.addBodyLine(sb.toString());
//        method.addBodyLine("LOGGER.info(result.toString());");
        return method;
    }

    /**
     * 新增接口
     */
    @Override
    public Method addMethod(String tableName, int flag) {
        Method method = new Method();
        method.setName("testAdd" + tableName);
        method.addAnnotation("@Test");
        method.setVisibility(JavaVisibility.PUBLIC);

        StringBuilder sb = new StringBuilder();
        String beanType = beanConfig.pojoType.getShortName();
        String bean = GeneratorUtil.toLowerCase(beanType);
        sb.append(beanType).append(" ").append(bean).append(" = new ").append(beanType).append("();");
        method.addBodyLine(sb.toString());
        sb.setLength(0);
        List<IntrospectedColumn> baseColumns = introspectedTable.getBaseColumns();
        for (int i = 0; i < baseColumns.size(); i++) {
            IntrospectedColumn column = baseColumns.get(i);
            sb.setLength(0);
            String columnName = column.getJavaProperty();
            columnName = columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
            sb.append(bean).append(".set").append(columnName);
            if (column.getFullyQualifiedJavaType().getShortName().equals("String")) {
                sb.append("(").append("\"cs_").append(GeneratorUtil.randomInt()).append("\");");
                method.addBodyLine(sb.toString());
            }
            if (column.getFullyQualifiedJavaType().getShortName().equals("Integer")) {
                sb.append("(").append(GeneratorUtil.randomInt()).append(");");
                method.addBodyLine(sb.toString());
            }
            if (column.getFullyQualifiedJavaType().getShortName().equals("Short")) {
                sb.append("(").append("(short) 1").append(");");
                method.addBodyLine(sb.toString());
            }
            if (column.getFullyQualifiedJavaType().getShortName().equals("Long")) {
                sb.append("(").append(GeneratorUtil.randomInt()).append("L);");
                method.addBodyLine(sb.toString());
            }
            if (column.getFullyQualifiedJavaType().getShortName().equals("Date")) {
                sb.append("(new Date());");
                method.addBodyLine(sb.toString());
            }
        }
        sb.setLength(0);
//        sb.append("Integer result = ");
        sb.append(GeneratorUtil.toLowerCase(interfaceType.getShortName())).append(".insert").append(tableName);
        sb.append("(");
        sb.append(bean);
        sb.append(");");
        method.addBodyLine(sb.toString());
//        method.addBodyLine("LOGGER.info(result.toString());");
        return method;
    }

}
